package cn.xchats.onlinetraffic.common.other.webdriver;

import cn.xchats.onlinetraffic.common.other.http.java.JavaHttpService;
import cn.xchats.onlinetraffic.common.other.util.PropertyUtil;
import lombok.Setter;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
 *
 *@author teddy
 *@date 2018/4/13
 */
@SuppressWarnings("all")
@Service
public class PhantomJsUtil {

    //所有cookie   key：账号
    public static Map<String, Set<Cookie>> loginCookieMap = new ConcurrentHashMap<>();

    //锁
    private static final Object lock = new Object();

    public static Integer port = 20000;

    //当前hander可支配线程的数量
    @Setter
    private Integer threadPoolSize;

    ExecutorService executorService;

    private static final StringBuffer jquery = new StringBuffer("");

    private static boolean initJquery = true;

    private boolean runEnvironmentLinux = Boolean.valueOf(PropertyUtil.getProperty("run.environment.linux"));//是否linux系统
    private String linuxChromedriverPath = String.valueOf(PropertyUtil.getProperty("run.environment.linux.chromedriver.path"));//linux系统下chromedriver路径
    private String windowChromedriverPath = String.valueOf(PropertyUtil.getProperty("run.environment.window.chromedriver.path"));//window系统下chromedriver路径
    private String linuxPhantomjsPath = String.valueOf(PropertyUtil.getProperty("run.environment.linux.phantomjs.path"));//linux系统下phantomjs路径
    private String windowPhantomjsPath = String.valueOf(PropertyUtil.getProperty("run.environment.window.phantomjs.path"));//window系统下phantomjs路径
    private String crxPath = String.valueOf(PropertyUtil.getProperty("chrome.crx.path"));//window系统下phantomjs路径



    public PhantomJsUtil() {
    }

    public PhantomJsUtil(Integer threadPoolSize) {
        this.threadPoolSize = threadPoolSize;
        executorService = Executors.newFixedThreadPool(this.threadPoolSize);
    }

    public static boolean isLinux() {
        return System.getProperty("os.name").toLowerCase().indexOf("linux") >= 0;
    }

    public WebDriver getChromeDriver() {
        String webdriverPath;
        webdriverPath = runEnvironmentLinux ? linuxChromedriverPath : windowChromedriverPath;
        //设置谷歌浏览器驱动，我放在项目的路径下，这个驱动可以帮你打开本地的谷歌浏览器
        System.setProperty("webdriver.chrome.driver", webdriverPath);

        // 设置对谷歌浏览器的初始配置           开始
        HashMap<String, Object> prefs = new HashMap<String, Object>();
        //设置禁止图片
        //prefs.put("profile.managed_default_content_settings.images", 2);
        //设置禁止cookies
        //prefs.put("profile.default_content_settings.cookies", 2);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs", prefs);
        DesiredCapabilities chromeCaps = DesiredCapabilities.chrome();
        chromeCaps.setCapability(ChromeOptions.CAPABILITY, options);
        // 设置对谷歌浏览器的初始配置           结束
        //添加拓展工具
        //options.addExtensions(new File("D:\\devTool\\phantomjs\\bin\\install.crx"));
        //新建一个谷歌浏览器对象（driver）
        WebDriver driver = null;
        //必定加载完插件
        try {
            //全屏
            List<String> op = new ArrayList<String>();
            op.add("start-fullscreen");
            op.add("allow-running-insecure-content");
            op.add("--test-type");
            //options.addArguments(op);

            driver = createChromeDriver(options);
            System.out.println("当前线程名->" + Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
            if (driver != null)
                driver.quit();
            synchronized (lock) {
                System.out.println("创建driver错误!!");
            }
        }
        return driver;
    }

    public WebDriver getDisplayChromeDriver() {
        String webdriverPath;
        webdriverPath = runEnvironmentLinux ? linuxChromedriverPath : windowChromedriverPath;
        //设置谷歌浏览器驱动，我放在项目的路径下，这个驱动可以帮你打开本地的谷歌浏览器
        System.setProperty("webdriver.chrome.driver", webdriverPath);

        // 设置对谷歌浏览器的初始配置           开始
        HashMap<String, Object> prefs = new HashMap<String, Object>();
        //设置禁止图片
        prefs.put("profile.managed_default_content_settings.images", 2);
        //设置禁止cookies
        prefs.put("profile.default_content_settings.cookies", 2);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs", prefs);
        DesiredCapabilities chromeCaps = DesiredCapabilities.chrome();
        chromeCaps.setCapability(ChromeOptions.CAPABILITY, options);
        // 设置对谷歌浏览器的初始配置           结束
        //添加拓展工具
        //options.addExtensions(new File("D:\\devTool\\phantomjs\\bin\\install.crx"));
        //新建一个谷歌浏览器对象（driver）
        WebDriver driver = null;
        //必定加载完插件
        try {
            //全屏
            List<String> op = new ArrayList<String>();
            op.add("start-fullscreen");
            op.add("allow-running-insecure-content");
            op.add("--test-type");
            //options.addArguments(op);

            driver = createChromeDriver(options);
            System.out.println("当前线程名->" + Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
            if (driver != null)
                driver.quit();
            synchronized (lock) {
                System.out.println("创建driver错误!!");
            }
        }
        return driver;
    }

    public WebDriver getDisplayChromeDriver(boolean crx) {
        String webdriverPath;
        webdriverPath = runEnvironmentLinux ? linuxChromedriverPath : windowChromedriverPath;
        //设置谷歌浏览器驱动，我放在项目的路径下，这个驱动可以帮你打开本地的谷歌浏览器
        System.setProperty("webdriver.chrome.driver", webdriverPath);

        // 设置对谷歌浏览器的初始配置           开始
        HashMap<String, Object> prefs = new HashMap<String, Object>();
        //设置禁止图片
        prefs.put("profile.managed_default_content_settings.images", 2);
        //设置禁止cookies
        prefs.put("profile.default_content_settings.cookies", 2);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs", prefs);
        DesiredCapabilities chromeCaps = DesiredCapabilities.chrome();
        chromeCaps.setCapability(ChromeOptions.CAPABILITY, options);
        // 设置对谷歌浏览器的初始配置           结束
        //添加拓展工具
        if (crx)
            options.addExtensions(new File(crxPath));
        //新建一个谷歌浏览器对象（driver）
        WebDriver driver = null;
        //必定加载完插件
        try {
            //全屏
            List<String> op = new ArrayList<String>();
            op.add("start-fullscreen");
            op.add("allow-running-insecure-content");
            op.add("--test-type");
            //options.addArguments(op);

            driver = createChromeDriver(options);
            System.out.println("当前线程名->" + Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
            if (driver != null)
                driver.quit();
            synchronized (lock) {
                System.out.println("创建driver错误!!");
            }
        }
        return driver;
    }

    public WebDriver getChromeDriver(boolean crx) {
        String webdriverPath;
        webdriverPath = runEnvironmentLinux ? linuxChromedriverPath : windowChromedriverPath;
        //设置谷歌浏览器驱动，我放在项目的路径下，这个驱动可以帮你打开本地的谷歌浏览器
        System.setProperty("webdriver.chrome.driver", webdriverPath);

        // 设置对谷歌浏览器的初始配置           开始
        HashMap<String, Object> prefs = new HashMap<String, Object>();
        //设置禁止图片
        //prefs.put("profile.managed_default_content_settings.images", 2);
        //设置禁止cookies
        //prefs.put("profile.default_content_settings.cookies", 2);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs", prefs);
        DesiredCapabilities chromeCaps = DesiredCapabilities.chrome();
        chromeCaps.setCapability(ChromeOptions.CAPABILITY, options);
        // 设置对谷歌浏览器的初始配置           结束
        //添加拓展工具
        //options.addExtensions(new File("D:\\devTool\\phantomjs\\bin\\install.crx"));

        //添加拓展工具
        if (crx)
            options.addExtensions(new File(crxPath));

        //新建一个谷歌浏览器对象（driver）
        WebDriver driver = null;
        //必定加载完插件
        try {
            //全屏
            List<String> op = new ArrayList<String>();
            op.add("start-fullscreen");
            op.add("allow-running-insecure-content");
            op.add("--test-type");
            //options.addArguments(op);

            driver = createChromeDriver(options);
            System.out.println("当前线程名->" + Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
            if (driver != null)
                driver.quit();
            synchronized (lock) {
                System.out.println("创建driver错误!!");
            }
        }
        return driver;
    }

    public WebDriver getChromeDriver(int width, int height) {
        if (runEnvironmentLinux) {
            //判断系统的环境win or Linux
            System.setProperty("webdriver.chrome.driver", linuxChromedriverPath);
        } else {
            //设置谷歌浏览器驱动，我放在项目的路径下，这个驱动可以帮你打开本地的谷歌浏览器
            System.setProperty("webdriver.chrome.driver", windowChromedriverPath);
        }

        // 设置对谷歌浏览器的初始配置           开始
        HashMap<String, Object> prefs = new HashMap<String, Object>();
        //设置禁止图片
        //prefs.put("profile.managed_default_content_settings.images", 2);
        //设置禁止cookies
        //prefs.put("profile.default_content_settings.cookies", 2);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("prefs", prefs);
        DesiredCapabilities chromeCaps = DesiredCapabilities.chrome();
        chromeCaps.setCapability(ChromeOptions.CAPABILITY, options);
        // 设置对谷歌浏览器的初始配置           结束
        //添加拓展工具
        //options.addExtensions(new File("D:\\devTool\\phantomjs\\bin\\install.crx"));
        //新建一个谷歌浏览器对象（driver）
        WebDriver driver = null;
        //必定加载完插件
        try {
            //全屏
            List<String> op = new ArrayList<String>();
            op.add("start-fullscreen");
            op.add("allow-running-insecure-content");
            op.add("--test-type");
            //options.addArguments(op);

            driver = createChromeDriver(options);
            driver.manage().window().setSize(new Dimension(width, height));
            System.out.println("当前线程名->" + Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
            if (driver != null)
                driver.quit();
            synchronized (lock) {
                System.out.println("创建driver错误!!");
            }
        }
        return driver;
    }


    private WebDriver createChromeDriver(ChromeOptions options) {
        //设置端口
        ChromeDriverService.Builder builder = new ChromeDriverService.Builder();
        ChromeDriverService chromeDriverService;
        synchronized (this) {
            chromeDriverService = builder.usingPort(port).build();
            ++port;
        }
        ChromeDriver driver = null;
        try {
            driver = new ChromeDriver(chromeDriverService, options);
        } catch (Exception e) {
            createChromeDriver(options);
            System.out.println("createWebDriver-error-->");
        }
        return driver;
    }

    public WebDriver getPhantomJs() {
        String webdriverPath;
        webdriverPath = runEnvironmentLinux ? linuxPhantomjsPath : windowPhantomjsPath;
        System.setProperty("phantomjs.binary.path", webdriverPath);//设置PhantomJs访问路径

        DesiredCapabilities desiredCapabilities = DesiredCapabilities.phantomjs();
        //desiredCapabilities.setCapability("phantomjs.page.settings.userAgent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0");
        //desiredCapabilities.setCapability("phantomjs.page.customHeaders.User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:50.0) Gecko/20100101 　　Firefox/50.0");
        synchronized (this) {
            return new PhantomJSDriver(desiredCapabilities);
        }
    }

    public void loginDomecrossExtension(WebDriver driver) {
        try {
            //等待穹顶穿越的标签页弹出
            while (true) {
                if (null != driver && null != driver.getWindowHandles() && driver.getWindowHandles().size() > 1)
                    break;
            }

            ArrayList<String> tabs = new ArrayList<String>(driver.getWindowHandles());
            int switchToCount = 1;
            //如果当前选项卡是穹顶穿越的，则不切换
            if ("chrome-extension://ldbcplcolkhgemejdgibfmhemnkecgni/login.html".equalsIgnoreCase(driver.getCurrentUrl())) {
                //TODO
            } else {
                //选择穹顶穿越的标签
                driver.switchTo().window(tabs.get(switchToCount));
                switchToCount = 0;
            }
            //智能等待穹顶page加载完毕
            WebDriverWait wait_1 = new WebDriverWait(driver, 20);
            wait_1.until(ExpectedConditions.presenceOfElementLocated(By.id("login_tab")));
            //会员登录
            driver.findElement(By.id("login_tab")).click();
            //智能等待表单页加载完毕
            WebDriverWait wait_2 = new WebDriverWait(driver, 20);
            wait_2.until(ExpectedConditions.presenceOfElementLocated(By.id("log_email")));
            //填写邮箱
            driver.findElement(By.id("log_email")).sendKeys("1084986263@qq.com");
            //填写密码
            driver.findElement(By.id("log_password")).sendKeys("a1084986263");
            //执行登录
            driver.findElement(By.id("logsub")).click();
            //智能等待添加域名代理页面加载完毕
            WebDriverWait wait_3 = new WebDriverWait(driver, 20);
            wait_3.until(ExpectedConditions.presenceOfElementLocated(By.id("domainAdd")));
            //添加域名代理的值
            driver.findElement(By.id("domainAdd")).sendKeys("http://www.huya.com");
            //driver.findElement(By.id("domainAdd")).sendKeys("http://pv.sohu.com");
            //执行添加域名代理
            driver.findElement(By.className("btn-success")).click();
            //添加代理完成,关闭页面
            driver.close();
            driver.switchTo().window(tabs.get(switchToCount)); //选择需要打开的标签
        } catch (Exception e) {
            loginDomecrossExtension(driver);
            System.out.println("填写穹顶穿越错误..!");
        }
    }

    public void execute() {

    }

    public void scrollTop(WebDriver webDriver, int count) {
        JavascriptExecutor webDriverJS = (JavascriptExecutor) webDriver;
        int size = 200;
        String builder = new String("document.documentElement.scrollTop=" + size);
        for (int i = 0; i < count; i++) {
            webDriverJS.executeScript(builder);
            int beforeSize = size;
            size += 200;
            builder = builder.replace(String.valueOf(beforeSize), String.valueOf(size));
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void scrollTop(WebDriver webDriver, int count, int sleepTime) {
        JavascriptExecutor webDriverJS = (JavascriptExecutor) webDriver;
        int size = 200;
        String builder = new String("document.documentElement.scrollTop=" + size);
        for (int i = 0; i < count; i++) {
            webDriverJS.executeScript(builder);
            int beforeSize = size;
            size += 200;
            builder = builder.replace(String.valueOf(beforeSize), String.valueOf(size));
            try {
                Thread.sleep(sleepTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 通过注入jQuery
    public String injectjQuery() {
        String result = "";
        try {
            String url = "http://libs.baidu.com/jquery/2.0.0/jquery.min.js";//"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js";
            result = JavaHttpService.getURLContent(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public String getJquery(WebDriver webDriver) {
        synchronized (this) {
            if (initJquery) {
                jquery.append(injectjQuery());
                initJquery = false;
            }
        }
        JavascriptExecutor webDriverJS = (JavascriptExecutor) webDriver;
        webDriverJS.executeScript(jquery.toString());
        return jquery.toString();
    }

    //cookie 登录
    public void cookieLogin(String userName, String url) {
        WebDriver phantomJs = getPhantomJs();
        addCookies(phantomJs, userName, url).get(url);
        synchronized (this) {
            System.out.println("已登录->");
        }
    }

    //cookie写到文件
    public void batchSerializableWrite(String filePath) {
        try {
            File file = new File(filePath);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
            objectOutputStream.writeObject(loginCookieMap);
            objectOutputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //cookie文件读出来
    public static void batchSerializableRead(String filePath) {
        try {
            File file = new File(filePath);
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
            loginCookieMap = (Map<String, Set<Cookie>>) objectInputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //给浏览器添加cookie
    private WebDriver addCookies(WebDriver webDriver, String userName, String url) {
        Set<Cookie> cookies = loginCookieMap.get(userName);
        webDriver.get(url);
        try {
            for (Cookie cookie : cookies) {
                webDriver.manage().addCookie(cookie);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return webDriver;
    }


    public void weiboLogin() {
        String filePath = "D:/weibocookie";
        String userName = "00639149217720";
        String password = "ywt345264n";
        WebDriver chromeDriver = getChromeDriver();
        chromeDriver.get("https://weibo.com/");
        String jquery = getJquery(chromeDriver);
        JavascriptExecutor webDriverJS = (JavascriptExecutor) chromeDriver;
        //等待登录按钮
        WebDriverWait wait_1 = new WebDriverWait(chromeDriver, 20);
        wait_1.until(ExpectedConditions.presenceOfElementLocated(By.className("gn_login_list")));
        //点击登录按钮
        chromeDriver.findElement(By.className("gn_login_list")).findElements(By.tagName("a")).get(1).click();
        //等待表单初始化
        WebDriverWait wait_2 = new WebDriverWait(chromeDriver, 20);
        wait_2.until(ExpectedConditions.presenceOfElementLocated(By.className("layer_login_register_v2")));
        //填写账号
        chromeDriver.findElement(By.className("layer_login_register_v2")).findElement(By.className("username")).findElement(By.tagName("input")).sendKeys(userName);
        //填写密码
        chromeDriver.findElement(By.className("layer_login_register_v2")).findElement(By.className("password")).findElement(By.tagName("input")).sendKeys(password);
        //执行登录
        chromeDriver.findElement(By.className("layer_login_register_v2")).findElements(By.className("W_btn_a")).get(0).click();
        //等待主页面加载完毕
        WebDriverWait wait_3 = new WebDriverWait(chromeDriver, 20);
        wait_3.until(ExpectedConditions.presenceOfElementLocated(By.className("func")));
        Set<Cookie> cookies = chromeDriver.manage().getCookies();

        //添加cookie
        loginCookieMap.put(userName, cookies);
        //序列化到文件
        batchSerializableWrite(filePath);
        System.out.println("执行完毕...");
    }

    public void weiboCookieLogin() {
        PhantomJsUtil phantomJsUtil = new PhantomJsUtil();
        phantomJsUtil.batchSerializableRead("D:/weibocookie");
        WebDriver webDriver = phantomJsUtil.addCookies(phantomJsUtil.getChromeDriver(), "00639149217720", "https://weibo.com/");
        webDriver.get("https://d.weibo.com/?topnav=1&mod=logo&wvr=6");// get("https://weibo.com/");
        //phantomJsUtil.scrollTop(webDriver,200,50);
        //一条微博下方的工具栏  WB_feed_handle
        /*List<WebElement> wb_feed_handle = webDriver.findElements(By.className("WB_feed_handle"));//.get(0).findElements(By.className("pos")).get(2).click();
        for (int i = 0; i < wb_feed_handle.size(); i++) {
            //第三个工具栏，也就是评论的元素  进行点击
            try {
                wb_feed_handle.get(i).findElements(By.className("pos")).get(2).click();
            } catch (Exception e) {
            }
        }*/
        phantomJsUtil.getJquery(webDriver);
        JavascriptExecutor webDriverJS = (JavascriptExecutor) webDriver;
        //关注用户们
        //String attention="$('.opt a').click();";
        String attention = "return document.getElementsByClassName('opt').getElementsByTagName('a').length";
        Object o1 = webDriverJS.executeScript(attention);

        //一条微博下方的工具栏  WB_feed_handle    ,第三个工具栏，也就是评论的元素  进行点击
        String clickComment = "var length=$('.WB_feed_handle').length; for (var i=0;i<length;i++){var currentLength=$('.WB_feed_handle:eq('+i+') .pos:eq(2)').click()}return length;";

        webDriverJS.executeScript(clickComment);
        //评论按钮 W_btn_a_disable
        //等待评论按钮加载完毕
        try {
            Thread.sleep(10_000);
        } catch (InterruptedException e) {
        }
        webDriverJS.executeScript("$('.p_input .W_input').val('高质量片 +++ V :xxxxx  https://g-search3.alicdn.com/img/bao/uploaded/i4/i2/2468045423/TB2oNeObTIlyKJjSZFMXXXvVXXa_!!2468045423.jpg_250x250.jpg')");
        //webDriverJS.executeScript("$('.btn  .W_btn_a').click()");
        //评论
        //等待评论的字写到输入框
        try {
            Thread.sleep(1_000);
        } catch (InterruptedException e) {
        }
        String comment = "var length=document.getElementsByClassName('W_btn_a').length;for (var i=0;i<length;i++){document.getElementsByClassName('W_btn_a')[i].click();} return length;";
        String commentLength = "return document.getElementsByClassName('W_btn_a').length;";
        Object o = webDriverJS.executeScript(comment);
        System.out.println("评论次数: >>>>>" + o);
    }

    public static void main(String[] args) {
        new PhantomJsUtil().weiboLogin();
        //new PhantomJsUtil().weiboCookieLogin();

    }
}
